Skip to content

Add first-class REST/OAuth provider type#21

Merged
BillJr99 merged 7 commits into
mainfrom
claude/rest-oauth-mcp-5j57tq
Jun 9, 2026
Merged

Add first-class REST/OAuth provider type#21
BillJr99 merged 7 commits into
mainfrom
claude/rest-oauth-mcp-5j57tq

Conversation

@BillJr99

@BillJr99 BillJr99 commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Introduce a new rest provider kind so a REST API can be wrapped as MCP
tools declaratively — no Python required. A provider YAML with a rest:
block declares a base URL, an auth: block, and endpoints (entered by
hand or imported from an OpenAPI 3.0 spec); each endpoint becomes an MCP
tool exposed on both the MCP server (8888) and the OpenAI-compatible REST
API (8889).

  • rest_provider.py: generic httpx handler routed through register_tool,
    a client_credentials token manager (cache/refresh), an
    authorization_code + PKCE token store (on-disk cache, interactive
    browser flow, refresh-token rotation), an auth resolver, and an
    OpenAPI 3.0 introspector.
  • server.py: a rest branch in register_provider (checked first; each
    tool maps 1:1 to an endpoint by name).
  • frontend/app.py: "REST / OAuth API" wizard step (auth-type fields,
    OpenAPI import + manual endpoints), editor rest-box with an Authorize
    button, plus /api/introspect-openapi, /api/rest-authorize, and
    /oauth/callback endpoints; pending auth links surface in the existing
    banner.
  • config.py / run_local.sh / docker-compose.yml: REST_AUTH_DIR and
    OAUTH_REDIRECT_BASE settings and token-cache volume.
  • requirements.txt: httpx promoted to a runtime dependency.
  • Tests: tests/test_rest_provider.py plus rest cases in test_server.py
    and test_frontend.py (387 passing).

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ

claude added 6 commits June 9, 2026 01:42
Introduce a new `rest` provider kind so a REST API can be wrapped as MCP
tools declaratively — no Python required. A provider YAML with a `rest:`
block declares a base URL, an `auth:` block, and endpoints (entered by
hand or imported from an OpenAPI 3.0 spec); each endpoint becomes an MCP
tool exposed on both the MCP server (8888) and the OpenAI-compatible REST
API (8889).

- rest_provider.py: generic httpx handler routed through register_tool,
  a client_credentials token manager (cache/refresh), an
  authorization_code + PKCE token store (on-disk cache, interactive
  browser flow, refresh-token rotation), an auth resolver, and an
  OpenAPI 3.0 introspector.
- server.py: a `rest` branch in register_provider (checked first; each
  tool maps 1:1 to an endpoint by name).
- frontend/app.py: "REST / OAuth API" wizard step (auth-type fields,
  OpenAPI import + manual endpoints), editor rest-box with an Authorize
  button, plus /api/introspect-openapi, /api/rest-authorize, and
  /oauth/callback endpoints; pending auth links surface in the existing
  banner.
- config.py / run_local.sh / docker-compose.yml: REST_AUTH_DIR and
  OAUTH_REDIRECT_BASE settings and token-cache volume.
- requirements.txt: httpx promoted to a runtime dependency.
- Tests: tests/test_rest_provider.py plus rest cases in test_server.py
  and test_frontend.py (387 passing).

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
The rich editor's REST box now supports editing the auth block (type +
conditional fields) and the endpoint list (name, method, path, and
path/query/body param routing) directly — previously these were only set
through the creation wizard.

Adding or removing an endpoint keeps its paired tool in sync (endpoints
map 1:1 to tools by name), renaming an endpoint renames its tool, and a
"⟳ Sync params to tool schema" action regenerates a tool's input schema
from its endpoint's params (preserving existing types/descriptions).

Adds a frontend test covering the editor save path (PUT with an added
endpoint + renamed tool) so auth and endpoints survive a round-trip.

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
Adds an end-to-end frontend test that drives the exact backend API
sequence the REST wizard performs: introspect an OpenAPI spec with the
real parser, assemble the provider as wzNext() does, POST it, read it
back, and assert the on-disk YAML (endpoint param classification, auth
block, surfaced secret keys).

Complements the static verification of the wizard/editor JavaScript
(node --check, HTML-handler→definition wiring, and eslint no-undef all
clean) by exercising the create → reload path through the HTTP API the
JS calls.

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
- Warm OAuth-backed REST providers at startup (mirrors the mcp-remote
  warm-up): client_credentials tokens are fetched/cached, and
  authorization_code providers with no usable token surface their
  authorize URL via the pending-auth banner immediately instead of only
  after the first failed tool call. Gated by MCPPROXY_WARM_REMOTE.
- Give in-flight authorization_code PKCE state a TTL (MCPPROXY_OAUTH_FLOW_TTL,
  default 600s) and prune stale entries on begin/complete, so a restart
  mid-flow or abandoned attempts don't leak state.
- Tests for provider discovery (_rest_oauth_providers) and flow pruning;
  README notes the warm-up behaviour and new env vars.

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
- Truncate oversized response bodies to a bounded preview with a
  `truncated` flag (MCPPROXY_REST_MAX_BYTES, default 100KB, 0 disables)
  so one call can't flood the model's context.
- Support api_key auth sent as a query parameter (`in: query` + `name`)
  in addition to a header; editor exposes a header/query toggle.
- Add an editable default-headers section to the REST editor box
  (serialized to a plain YAML mapping on save).
- Tests for all three plus a header/api_key round-trip; README updated.
  Wizard/editor JS re-verified (node --check, handler wiring, eslint
  no-undef all clean). 400 tests passing.

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
The introspector now handles both OpenAPI 3.x and Swagger 2.0 specs:
- Swagger 2.0 `in: body` parameters expand their schema's properties
  into body params; `in: formData` maps to body params; param types are
  read from `param.type` (2.0) or `param.schema.type` (3.x).
- Object schemas merge `allOf` (resolving `#/components/...` and
  `#/definitions/...` refs) so composed request bodies import correctly.

Adds tests for Swagger 2.0 param classification and allOf merging.
402 tests passing; README notes 2.0/3.x support.

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
Copilot AI review requested due to automatic review settings June 9, 2026 02:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a first-class rest provider type so users can declaratively wrap REST APIs as MCP tools (including OAuth flows), without writing Python code. It introduces a REST provider runtime (rest_provider.py), wires REST provider registration into the MCP server, and extends the UI to create/edit REST providers and run OAuth authorization_code + PKCE.

Changes:

  • Added rest_provider.py with REST request handling, auth resolvers (none/bearer/api_key/OAuth), token caching, and OpenAPI/Swagger introspection.
  • Updated server registration to support rest: providers and added startup warm-up for OAuth-backed REST providers.
  • Extended the frontend to support a “REST / OAuth API” wizard/editor, OpenAPI introspection endpoint, and OAuth callback/authorize endpoints; added comprehensive tests.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
server.py Registers REST providers and adds REST OAuth warm-up on startup.
rest_provider.py Implements REST tool handler, OAuth token management, and OpenAPI/Swagger parsing.
frontend/app.py Adds REST provider CRUD support in UI, OpenAPI introspection API, and OAuth authorize/callback endpoints plus editor/wizard UI.
README.md Documents REST/OAuth providers, auth modes, example YAML, and config knobs.
config.py Adds REST_AUTH_DIR and OAUTH_REDIRECT_BASE settings.
docker-compose.yml Persists REST OAuth token cache via a new volume and env var.
run_local.sh Adds local default for MCPPROXY_REST_AUTH_DIR.
requirements.txt Adds httpx as a runtime dependency.
.gitignore Ignores .rest-auth/ token cache directory.
tests/test_rest_provider.py Adds unit tests for REST provider behavior, OAuth managers, and OpenAPI parsing.
tests/test_server.py Adds tests for REST branch detection and OAuth REST provider discovery.
tests/test_frontend.py Adds REST provider UI/backend tests including wizard flow and OAuth endpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/app.py
Comment thread frontend/app.py
Comment thread server.py
Comment thread rest_provider.py
- /oauth/callback: HTML-escape the `error` query param and exception text
  before embedding them in the response (reflected-XSS fix).
- /api/introspect-openapi: restrict local spec paths to the files
  directory (no arbitrary file reads like .env) and run the blocking
  fetch/parse in a worker thread so it can't block the UI event loop.
- OAuth token managers: make the asyncio lock loop-safe so a manager
  cached by the startup warm-up thread can be reused from the MCP server
  loop without "bound to a different loop" errors.
- introspect_openapi: drop the unused `base_url` parameter (and stop the
  wizard from sending it).

Tests for callback escaping, path traversal/containment, and cross-loop
token-manager reuse. 407 passing; wizard/editor JS re-verified.

https://claude.ai/code/session_01L9uGbkXi2RwUmBQHdVaNoZ
@BillJr99 BillJr99 merged commit 4c4cebf into main Jun 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants